/*
 * @Author: “ygnnli” “1585923072@qq.com”
 * @Date: 2024-08-05 09:03:18
 * @LastEditors: “ygnnli” “1585923072@qq.com”
 * @LastEditTime: 2024-08-05 10:45:01
 * @FilePath: /110/54/net_cal/TcpClientMain.cc
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include <iostream>
#include "Protocol.hpp"
#include "Socket.hpp"
#include <string>
#include <memory>
#include "InetAddr.hpp"
#include <ctime>
#include <unistd.h>

using namespace socket_ns;
using namespace protocol_ns;

// 输入格式不对
void Usage(std::string proc)
{
    std::cout << "Usage: \n\t" << proc << "loacl_ip  local_port\n"
              << std::endl;
}

// ./tcpclient serverip  serverport
int main(int arg, char *argv[])
{

    if (arg != 3)
    {
        Usage(argv[0]);
        exit(1);
    }
    std::string serverip = argv[1];
    uint16_t serverport = std::stoi(argv[2]);

    InetAddr serveraddr(serverip, serverport); // 服务器地址

    Factory factory;                                             // 工厂对象
    std::unique_ptr<Socket> cli = std::make_unique<TcpSocket>(); // 创建客户端对象
    bool res = cli->BuildClientSocket(serveraddr);               // 创建客户端套接字 + 发送请求
    std::string inbuffer;                                        // 接收缓冲区
    while (res)
    {
        sleep(1);
        // std::string str;
        //  for (int i = 0; i < 5; i++)
        //  {
        //      // 1.创建一个请求
        //      auto req = factory.BuildRequest();

        //     // 2. 对请求进行序列化
        //     std::string send_str;
        //     req->Serialize(&send_str);
        //     std::cout << "Serialize: \n"
        //               << send_str << std::endl; // 输出序列化结果

        //     // 3. 添加长度报头
        //     send_str = Encode(send_str);
        //     std::cout << "Encode: \n"
        //               << send_str << std::endl; // 发送的编码结果

        //     str += send_str;
        // }

        // 1.创建一个请求
        auto req = factory.BuildRequest();

        // 2. 对请求进行序列化
        std::string send_str;
        req->Serialize(&send_str);
        std::cout << "Serialize: \n"
                  << send_str << std::endl; // 输出序列化结果

        // 3. 添加长度报头
        send_str = Encode(send_str);
        std::cout << "Encode: \n"
                  << send_str << std::endl; // 发送的编码结果

        // 4. "len"\r\n"{}"\r\n
        cli->Send(send_str); // 发送请求

        // 5. 读取应答
        int n = cli->Recv(&inbuffer);
        if (n <= 0)
            break;
        std::string package = Decode(inbuffer);
        if (package.empty())
            continue;

        // 6. 我能保证package一定是一个完整的应答
        auto resp = factory.BuildResponse();
        // 6.1 反序列化
        resp->Deserialize(package);

        // 7. 拿到了结构化的应答
        std::cout << resp->_result << "[" << resp->_code << "]" << std::endl; // 输出结果
    }
}